#include "socket.h"
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <cstdlib>
#include <iostream>

Socket::Socket(const std::string& ip, uint16_t port) {
    sockfd_ = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
    if (sockfd_ < 0) {
        perror("socket");
        std::exit(EXIT_FAILURE);
    }

    std::memset(&addr_, 0, sizeof(addr_));
    addr_.sin_family = AF_INET;
    addr_.sin_port = htons(port);
    if (::inet_pton(AF_INET, ip.c_str(), &addr_.sin_addr) <= 0) {
        perror("inet_pton");
        std::exit(EXIT_FAILURE);
    }
}

Socket::~Socket() {
    ::close(sockfd_);
}

void Socket::setReuseAddr(bool on) {
    int opt = on ? 1 : 0;
    if (::setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
        perror("setsockopt SO_REUSEADDR");
    }
}

void Socket::bind() {
    if (::bind(sockfd_, (sockaddr*)&addr_, sizeof(addr_)) < 0) {
        perror("bind");
        std::exit(EXIT_FAILURE);
    }
}

void Socket::listen() {
    if (::listen(sockfd_, SOMAXCONN) < 0) {
        perror("listen");
        std::exit(EXIT_FAILURE);
    }
}
